/**
 *
 */
package com.wedroid.r2d2.message.parser;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.wedroid.entity.message.MessageType;
import com.wedroid.r2d2.message.RawMessage;

/**
 * @author lute
 */
@Component
public class CompositeContentParser implements ContentParser {

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private List<ContentParser> contentParsers;

    private final Map<MessageType, ContentParser> contentParserCache = new HashMap<>(32);

    /* (non-Javadoc)
     * @see com.wedroid.r2d2.message.parser.ContentParser#parse(com.wedroid.r2d2.message.RawMessage, java.lang.String)
     */
    public String parse(RawMessage rawMessage, String escapedContent) {
        MessageType messageType = MessageType.codeOf(rawMessage.getMsgType());
        ContentParser contentParser = getContentParser(messageType);
        if (contentParser == null) {
            return "[Unsupported message type: " + messageType.name() + "]";
        }
        return contentParser.parse(rawMessage, escapedContent);
    }

    /* (non-Javadoc)
     * @see com.wedroid.r2d2.message.parser.ContentParser#supportsMessageType(com.wedroid.entity.message.MessageType)
     */
    public boolean supportsMessageType(MessageType messageType) {
        return (getContentParser(messageType) != null);
    }

    /**
     * @param messageType
     * @return
     */
    private ContentParser getContentParser(MessageType messageType) {
        ContentParser result = contentParserCache.get(messageType);
        if (result == null) {
            for (ContentParser contentParser : contentParsers) {
                logger.trace("#getContentParser - Testing if content parser [{}] supports message type [{}].", contentParser, messageType);
                if (contentParser.supportsMessageType(messageType)) {
                    result = contentParser;
                    contentParserCache.put(messageType, contentParser);
                    break;
                }
            }
        }
        return result;
    }

}
